package service

import (
	"context"
	"forum/app/post/internal/repository/db/dao"
	pb "forum/idl/pb/post"
	"forum/pkg/e"
	"sync"
)

var PostSrvIns *PostSrv
var PostSrvOnce sync.Once

type PostSrv struct {
	pb.UnimplementedPostServiceServer
}

func GetPostSrv() *PostSrv {
	PostSrvOnce.Do(func() {
		PostSrvIns = &PostSrv{}
	})
	return PostSrvIns
}

func (p *PostSrv) PostCreate(ctx context.Context, req *pb.PostRequest) (resp *pb.PostCommonResponse, err error) {
	resp = new(pb.PostCommonResponse)
	resp.Code = e.SUCCESS
	err = dao.NewPostDao(ctx).CreatePost(req)
	if err != nil {
		resp.Code = e.ErrorPostCreate
		resp.Msg = e.GetMsg(int(resp.Code))
		resp.Data = err.Error()
		return
	}
	return
}

func (p *PostSrv) PostUpdate(ctx context.Context, req *pb.PostRequest) (resp *pb.PostCommonResponse, err error) {
	resp = new(pb.PostCommonResponse)
	resp.Code = e.SUCCESS
	err = dao.NewPostDao(ctx).UpdatePost(req)
	if err != nil {
		resp.Code = e.ErrorPostUpdate
		resp.Msg = e.GetMsg(int(resp.Code))
		resp.Data = err.Error()
		return
	}
	return
}

func (p *PostSrv) PostDelete(ctx context.Context, req *pb.PostRequest) (resp *pb.PostCommonResponse, err error) {
	resp = new(pb.PostCommonResponse)
	resp.Code = e.SUCCESS
	err = dao.NewPostDao(ctx).DeletePost(req)
	if err != nil {
		resp.Code = e.ErrorPostDelete
		resp.Msg = e.GetMsg(int(resp.Code))
		resp.Data = err.Error()
		return
	}
	return
}

func (p *PostSrv) PostShow(ctx context.Context, req *pb.PostRequest) (resp *pb.PostDetailResponse, err error) {
	resp = new(pb.PostDetailResponse)
	resp.Code = e.SUCCESS
	if req.Page <= 0 {
		req.Page = 1
	}
	if req.PageSize <= 0 {
		req.PageSize = 10
	}
	r, err := dao.NewPostDao(ctx).ShowPostByUserId(req)
	if err != nil {
		resp.Code = e.ERROR
		return
	}
	for i := range r {
		resp.PostDetail = append(resp.PostDetail, &pb.PostModel{
			PostID:     uint64(r[i].ID),
			UserID:     uint64(r[i].UserId),
			Title:      r[i].Title,
			Content:    r[i].Content,
			Status:     r[i].Status,
			CreateTime: r[i].CreatedAt.Unix(),
			UpdateTime: r[i].UpdatedAt.Unix(),
		})
	}
	resp.Total = uint32(len(r))
	return
}

func (p *PostSrv) PostShowOne(ctx context.Context, req *pb.PostRequest) (resp *pb.PostDetailResponse, err error) {
	resp = new(pb.PostDetailResponse)
	resp.Code = e.SUCCESS
	r, err := dao.NewPostDao(ctx).ShowPostByUserIdAndPostId(uint(req.UserID), uint(req.PostID))
	if err != nil {
		resp.Code = e.ERROR
		return
	}
	for i := range r {
		resp.PostDetail = append(resp.PostDetail, &pb.PostModel{
			PostID:     uint64(r[i].ID),
			UserID:     uint64(r[i].UserId),
			Title:      r[i].Title,
			Content:    r[i].Content,
			Status:     r[i].Status,
			CreateTime: r[i].CreatedAt.Unix(),
			UpdateTime: r[i].UpdatedAt.Unix(),
		})
	}
	resp.Total = uint32(len(r))
	return
}
